#!/home/dmitry/scripts/env/bin/python
""" 
Callback script for flow-capture rotate event
Runs main monitor script
"""
import pprint
import argparse
import logging
import logging.config
import os
import traceback
import sys
import subprocess
import ipaddress 
import time
import fcntl

import lock
import mon
import report

from config import *

logging.config.fileConfig(LOGGING_CONF)
logger = logging.getLogger('dmzwatch.'+__name__)

def retrieve_addrs(file):
    """ 
    Form ip->interface pair from flow-tools data presented in 'file'.
        Returns dictionary 'ip' -> 'interface'
    """
    try:
        with open(file): pass
    except IOError:
        logger.error('Something wrong with file: %s. exiting...', file)
        raise
    
    command = "flow-cat " + file + " | " + "flow-report" + " -Ssource "
    logger.info('Running command: %s', command)
    try:
        source = subprocess.check_output(command,shell=True)
    except subprocess.CalledProcessError as e:
        logger.debug('Command execution failed. Returned status: %s. Exiting...', e.returncode)
        raise
    
    command = "flow-cat " + file + " | " + "flow-report" + " -Sdestination " 
    logger.info('Running command: %s', command)
    
    try:
        destination = subprocess.check_output(command, shell=True)
    except subprocess.CalledProcessError as e:
        logger.error('Command execution failed. Returned status: %s. Exiting...', e.returncode)
        raise
    
    addresses = {} 
    
    for flow in source.split()[3:]:
        attributes = flow.decode("ascii").split(',')
        if ipaddress.ip_address(attributes[0]).is_private:
            addresses[attributes[0]] = attributes[1] 
    
    
    for flow in destination.split()[3:]:
        attributes = flow.decode("ascii").split(',')
        if ipaddress.ip_address(attributes[0]).is_private:
            addresses[attributes[0]] = attributes[1]         
    
    logger.debug('Number of addresses: %d', len(addresses))
    
    return addresses

    
if __name__ == "__main__":

    WORKING_DIR = os.getcwd()
    parser = argparse.ArgumentParser()
    parser.add_argument('file', help="Flow-tools file")
    args = parser.parse_args()
    
    #Non BLOCKING!    
    fp = open('lockfile', 'w')
    try:
        fcntl.lockf(fp, fcntl.LOCK_EX | fcntl.LOCK_NB)
    except IOError:
        logger.warning('Cannot acquire lockfile')
        exit(-1)
        
    file = args.file
    logger.debug('---------START---------')
    try:
        addrs = retrieve_addrs(file)
    except:
        report.dmzwatch_error(  
                            'CANNOT RETRIEVE ADRESSES!',
                            Severity.high, 
                            *sys.exc_info()
                          )
        logger.debug('---------ERROR END---------')
        exit(-1)
    logger.debug('---------STARTING MONITOR---------')    
    try:
        mon.main(addrs)
    except Exception as e:
        report.dmzwatch_error(  
                    'CRITICAL FLOW MONITOR ENGINE ERROR',
                    Severity.high, 
                    *sys.exc_info()
                  )
        logger.debug('---------ERROR END---------')
        exit(-2)
        
    logger.debug('---------DONE---------')
    exit(0)
    
    
